/*==============================================================================
**                                  LINDBOARD
**                      Proprietary - Copyright (C) 2014
**                      www.facebook.com/lindboard
**------------------------------------------------------------------------------
** Supported MCUs      : MCU STM32F10x
** Supported Compilers : KeilC
**------------------------------------------------------------------------------
** File name         : COM.c
**  
** Module name       : The Matrix Keypad 4x4
**
** Summary: 
**
**= History ===================================================================
** 00.00.01  17/7/2014  Cuong Chu
**           - Creation
==============================================================================*/
/******************************************************************************/
/* INCLUSIONS                                                                 */
/******************************************************************************/
#include "stm32f10x.h"
#include "bsp/output.h"
#include "bsp/input.h"
#include "keypad/keypad.h"
#include "bsp/bsp.h"
/*******************************************************************************/
/* DEFINITION OF MACROS                                                        */
/*******************************************************************************/
#define KEYP_Delayms(x)     {;} /* put delay function here */
/******************************************************************************/
/* DEFINITION OF LOCAL VARIABLE                                               */
/* scanning table values */
static const uint8_t ScanningValue[] =
{
 0x7F,
 0xBF,
 0xDF,
 0xEF
};
/******************************************************************************/
/* DEFINITION OF CONSTANTS                                                    */
/******************************************************************************/
#define NULL_PTR ((void *)0)

/******************************************************************************/
/* DEFINITION OF LOCAL FUNCTIONS                                             */
/******************************************************************************/
/* read value on keypad port */
static uint8_t KEYP_ReadPort
(
  void
)
{
  uint8_t value = 0x00;
  value |= INPUT_ReadInput(IN_CH_C0) << 0;
  value |= INPUT_ReadInput(IN_CH_C1) << 1;
  value |= INPUT_ReadInput(IN_CH_C2) << 2;
  value |= INPUT_ReadInput(IN_CH_C3) << 3;
  return ~value;
}
/* output to key port */
static void KEYP_WritePort
(
  uint8_t index
)
{
  uint8_t value = ScanningValue[index];
  value >>= 4;
  value &= 0x0f;
  OUTPUT_OutputSetLogic(OUT_KEYP_R0,(COMST32_LogicLevel)((value >> 3) & 1UL)); 
  OUTPUT_OutputSetLogic(OUT_KEYP_R1,(COMST32_LogicLevel)((value >> 2) & 1UL)); 
  OUTPUT_OutputSetLogic(OUT_KEYP_R2,(COMST32_LogicLevel)((value >> 1) & 1UL)); 
  OUTPUT_OutputSetLogic(OUT_KEYP_R3,(COMST32_LogicLevel)((value >> 0) & 1UL)); 

}
/******************************************************************************/
/* DEFINITION OF GLOBAL FUNCTIONS                                             */
/******************************************************************************/
/*******************************************************************************
** Function name: KEYP_Init( void  )
** Description  : The function initialize keypad module          
** Parameter    : none
** Return value : none
** Remarks      : global variables used, side effects
*******************************************************************************/
void KEYP_Init
(
  void
)
{
  /* enable io clock supply */
  INPUT_IOEnableClock();
  /* init hardware pin */
  /* init C0..C3 at input */
  INPUT_InputInit(IN_CH_C0);
  INPUT_InputInit(IN_CH_C1);
  INPUT_InputInit(IN_CH_C2);
  INPUT_InputInit(IN_CH_C3);
  /* init R0..R3 at input */
  OUTPUT_OutputInit(OUT_KEYP_R0);
  OUTPUT_OutputInit(OUT_KEYP_R1);
  OUTPUT_OutputInit(OUT_KEYP_R2);
  OUTPUT_OutputInit(OUT_KEYP_R3);
  /* default high level on scan port */
  OUTPUT_OutputSetLogic(OUT_KEYP_R0,STD_HIGH);
  OUTPUT_OutputSetLogic(OUT_KEYP_R1,STD_HIGH);
  OUTPUT_OutputSetLogic(OUT_KEYP_R2,STD_HIGH);
  OUTPUT_OutputSetLogic(OUT_KEYP_R3,STD_HIGH);
}
/*******************************************************************************
** Function name: KEYP_ScanKey( void  )
** Description  : The function scan keypad
** Parameter    : None
** Return value : Value valid on keypad, see in KEYP_KeyType
** Remarks      : global variables used, side effects
*******************************************************************************/
KEYP_KeyType KEYP_ScanKey
(
  void
)
{
  KEYP_KeyType key = KEY_INVALID;
  uint8_t      i = 0;
  uint8_t      KeyDecoder;
  uint8_t      KeepGoing = 1;
  uint8_t      ReadValue;
  /* loop scan */
  while(KeepGoing && i < 4)
  {
    /* store scan value for calculate key hit */
    KeyDecoder = ScanningValue[i];
    KeyDecoder = ~KeyDecoder;
    KeyDecoder &= 0xF0;
    /* read data from colum port, if key hit, 
    values will be stored */
    KEYP_WritePort(i);
    ReadValue = KEYP_ReadPort();
    if(ReadValue != 0xF0)
    {
      ReadValue &= 0x0F;
      /* decode key value */
      KeyDecoder |= ReadValue;
      /* value is according with specified key */
      switch(KeyDecoder)
      {
        case 0x18: key = KEY_D;     break;
        case 0x14: key = KEY_HASH;  break;
        case 0x12: key = KEY_0;     break;
        case 0x11: key = KEY_ATK;   break;  
        case 0x28: key = KEY_C;     break;
        case 0x24: key = KEY_9;     break;
        case 0x22: key = KEY_8;     break;
        case 0x21: key = KEY_7;     break;
        case 0x48: key = KEY_B;     break;
        case 0x44: key = KEY_6;     break;
        case 0x42: key = KEY_5;     break;
        case 0x41: key = KEY_4;     break;
        case 0x88: key = KEY_A;     break;
        case 0x84: key = KEY_3;     break;
        case 0x82: key = KEY_2;     break;
        case 0x81: key = KEY_1;     break;
        default: break;
      }
      /* exit loop */
      KeepGoing = 0;
    }
    else
    {
      /* do nothing */
    }
    i++;
  }
  
  return key;
}
/*****************************************************************************/
/* End Of File Copyright Cuong Chu 2014 - manhcuong.k08@gmail.com            */ 
/*****************************************************************************/
